AWS Lakeformationを使ってData Lakeを構成してみた
データアナリティクス事業本部のnkhrです。今回のブログでは、Data Lakeのアクセス管理やデータ管理を行うLake Formation機能を検証します。
Lake Formationを使うメリット
Data Lakeアーキテクチャでデータ格納・加工・クエリを実施するためには、複数のAWSサービスを組み合わせる必要があります。
たとえば、Lake Formationを利用せずに、以下のようなAWSサービスを組み合わせる場合、IAM PolicyとBucket Policyを用いて、どのデータに対して誰がアクセスしてよいかを制御(データガバナンス)する必要があり、ポリシーの管理は複雑になります。
- S3(データ格納)
- Gule Data Catalog (S3データのSchema定義)
- Glue Data Brew or Glue ETL(データ加工/ジョブ)
- Step Function or AWAA(ジョブ管理)
- Athena(クエリ)
各AWSサービスからData LakeへのアクセスをLake Formation経由で管理できます。Lake Formationというアクセスレイヤを挟むことで、アクセス制御を一元的に管理します。
今回の検証では、以下のイメージを検証します。
Lake Formation開始のための前準備
サンプルデータおよび、Lake Formationの管理者ユーザ、テストユーザ、Glue crawler実行ロールを準備します。
サンプルデータセットの準備
AWSが提供しているOpen Dataset(Helpful Sentences from Reviews)を利用します。
Helpful Sentences from Reviewsデータセットは、カスタマーレビューから抽出した文章を、その有用性スコアでラベリングしたものです。S3バケットでデータが公開されているため、AWS CLIで2ファイル取得しました。
$ aws s3 cp s3://helpful-sentences-from-reviews/test.json . --no-sign-request $ aws s3 cp s3://helpful-sentences-from-reviews/train.json . --no-sign-request
S3 Bucketの準備
「test-lakeformation-xxx」のバケットを作成し、下記のパス構成でファイルを格納します。
- 上記のように名称のみのパス(フォルダ)を作成した場合、crawlerで自動判別したパーティション名は「partition_0」となります。パーティション名を任意の名前(例:categlory)にする場合は次のようなパスにします(パーティション名=パーティション値)。
- s3://category=test/
- s3://category=train/
ユーザ準備
Lake Formation開始前に、ユーザとRoleを作成します。Lake Formationの権限の詳細についてはユーザタイプ(管理者、データエンジニア、データアナリスト)ごとに公式サイトでまとめられています。
- DataLake管理者ユーザ
- グループ名:lf_admins
- ユーザ名: test_admin_user
- Managed Policy: AWSLakeFormationDataAdmin (DataLake管理者の基本ポリシー)
- lakeformationに関する全ての操作権限
- cloudtrailのDescribe/Lookup Event権限
- glueのDatabase, Table, Connection, WorkflowのGetやUpdate、Delete権限など
- s3のバケットList、ACLのGet権限
- iamのList Users/Roles, Get Role/RolePolicy権限
- Inline Policy - LakeformationのServiceLinked roleの作成およびPolicyの追加権限
- Lake FormationでS3のLocationを追加した際にS3アクセス権限のRole作成または、ServiceLined roleへのポリシー追加を行う必要があります。以下のInline policyを持つことで自動でServiceLinked Roleに追加したS3 Locationへのアクセス権限(PutObject/GetObject/DeleteObject)が付与されます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:CreateServiceLinkedRole", "Resource": "*", "Condition": { "StringEquals": { "iam:AWSServiceName": "lakeformation.amazonaws.com" } } }, { "Effect": "Allow", "Action": [ "iam:PutRolePolicy" ], "Resource": "arn:aws:iam::<account-id>:role/aws-service-role/lakeformation.amazonaws.com/AWSServiceRoleForLakeFormationDataAccess" } ] }
- Lake FormationでS3のLocationを追加した際にS3アクセス権限のRole作成または、ServiceLined roleへのポリシー追加を行う必要があります。以下のInline policyを持つことで自動でServiceLinked Roleに追加したS3 Locationへのアクセス権限(PutObject/GetObject/DeleteObject)が付与されます。
- (Option) Data Formation管理者を追加する
- lakeformation:PutDataLakeSettings
- lakeformation:GetDataLakeSettings
- (Option) Lake FormationのBlueprintからGlue Workflowを作成した際のトラブルシューティング
- AWSGlueConsoleFullAccess
- CloudWatchLogsReadOnlyAccess
- (Optional) Data Catalogリソースに対するクロスアクセス権限を付与する(他のアカウントへの付与)
- AWSLakeFormationCrossAccountManager
- (Optional) 他のアカウントから提供されるクロスアクセスを受け入れる(他のアカウントからの付与)
- 以下のinline policyを追加
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ram:AcceptResourceShareInvitation", "ram:RejectResourceShareInvitation", "ec2:DescribeAvailabilityZones", "ram:EnableSharingWithAwsOrganization" ], "Resource": "*" }]}
- 以下のinline policyを追加
- (Optional) Athenaでクエリを実行する
- AmazonAthenaFullAccess
- (Option) Workflowが実行できるようにする
- 「AWSGlueServiceRole」ポリシー(Roleって名前ついてますがManaged Policy)を持つ「LakeFormationWorkflowRole」Roleを作成する
- LakeFormationWorkflowRoleロールを「iam:PassRole」できるinline policyを追加する
- (Optional) Glueサービスを操作する
- 通常の管理者権限としては無くてよいです。今回はテーブル定義をCrawlerで作成するため以下を追加しました。検証のためFullAccessを使っていますが、必要に応じて権限を絞ってください。
- AWSGlueConsoleFullAccess
- CloudWatch Logs:LogGroup「/aws-glue/crawlers」のDescribe権限
- Actions
- logs:DescribeLogStreams
- logs:GetLogEvents
- logs:FilterLogEvents
- Resource (特定のStreamに絞る場合はアスタリスク以降を修正)
- arn:aws:logs:::log-group:/aws-glue/crawlers*
- Actions
- DataLake利用ユーザ:テーブルデータ取得、データ検索、タグによる検索ユーザ
- グループ名:lf_users
- ユーザ名:test_user
- Basic Policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lakeformation:GetDataAccess", "glue:GetTable", "glue:GetTables", "glue:SearchTables", "glue:GetDatabase", "glue:GetDatabases", "glue:GetPartitions", "lakeformation:GetResourceLFTags", "lakeformation:ListLFTags", "lakeformation:GetLFTag", "lakeformation:SearchTablesByLFTags", "lakeformation:SearchDatabasesByLFTags" ], "Resource": "*" }]}
- (Optional) Athenaによるクエリを実行したい場合 (今回はアクセスするため追加)
- AmazonAthenaFullAccess (適切な権限に絞る場合Managed Policyはないため、通常はCustom Policyを作成します)
- AmazonS3FullAccess (Athenaの結果格納、検証のためFullAccess権限を付与しています)
今回はテーブル作成をGlueのCrawler経由で行うため、Crawlerで利用するRoleを作成します。
- Role Name:AWSGlueServiceRoleDefaultDataLakeDataAccess
- Type of Trusted entity:Glue
- Managed Policy
- AWSGlueServiceRole
- AmazonS3ReadOnlyAccess
- InlinePolicy:Lakeformationの利用権限を追加
- lakeformation:GetDataAccess
- lakeformation:GetResourceLFTags
- lakeformation:ListLFTags
- lakeformation:GetLFTag
Lake Formationの設定
Lake Formationの管理者追加
「AWSLakeFormationDataAdmin」マネージドポリシーのみでは、Lake Formationの管理者追加は行えない。そのため、実行できる権限を持ったユーザでLake Formation管理者用ユーザ(test_admin_user)を管理者に追加する。
<管理者追加に必要なポリシー>※Lake Formation管理者ユーザ自身が管理者追加する場合は、以下の権限をinline Policyで追加する
- lakeformation:PutDataLakeSettings
- lakeformation:GetDataLakeSettings
Lake Formationで不要な権限解除
Lake Formationでアクセス制御を一元管理するために不要な権限設定を解除します。
- IAM access controlのみを利用したDatabase/Tableへのアクセス制御を無効化
- 下記画像のようにチェックボックスが外れていること
- Lake FormationではIAM Access Controlに、Lake Formationのアクセス制御レイヤーを追加し、アクセス制御をLake Formationで一元管理できるようにします。チェックを入れるとLake Formationによるアクセス制御レイヤーを利用せずにIAM Access Control (IAM Policyの権限)のみでDatabaseやTableに接続できるようになります。
-
IAM権限のみで、Lake FormationのDatabase作成ができる状態を無効化
- 「Administrative roles and tasks」の「Database creators」から「IAMAllowedPrincipals」を削除
Lake Formation管理者ユーザでログイン
準備で作成した管理者ユーザでログインし、Lake Formationのコンソールを表示します。
アクセス制御用のタグ追加
LF-Tagsからアクセス制御に利用するタグを追加します。今回は以下のタグを追加しました。
- Tag Key:maintenance ← DatabaseをCrawlingするためのLF-Tag
- Tag Values
- cralwer
- manual
- Tag Values
- Tag Key:source
- Tag Values ←ユーザ制御のためにTableに付与するLF-Tag
- helpful_sentences
- Tag Values ←ユーザ制御のためにTableに付与するLF-Tag
<Data Lake Permission>
作成したタグが付与されたリソースをGlue Crawler用のRole「AWSGlueServiceRoleDefaultDataLakeDataAccess」に設定します。「data lake permission」から、LF-tag(maintenance/cralwer)が付与されたDatabase/Tableに対するSuper権限を付与します。
また、テストユーザ「test_user」がTag (source/helpful_sentences)権限によりTable操作ができるように、TABLEに対するSELECT, Describe権限を付与します。
現時点では、IAMのグループ単位での権限付与ができないため、UserまたはRole単位でTag権限を登録する必要があります。Userごとは人数が増えた場合の管理が難しいため、権限ごとのRoleを作成し、ユーザがSwitch Roleする方法や、SAML認証などの権限管理方法を検討する必要があります。
Data Lake Locationの追加
データが保存されているS3 BucketをData Lake locationsに登録します。Data Lake Locationに追加することで、追加されたS3 bucket (path)へのアクセスをLake Formationで管理します。ユーザに登録RoleへのputRolePolicy権限がある場合、登録したS3パスへの接続権限が自動で登録Roleに付与されます。
- 他アカウントのBucketを登録する場合は、service-linked roleではなく、Customer roleを利用します。また、他アカウントのBucket Policyに、利用ロールからの明示的な接続許可を行います。
- BucketにRequester pays (リクエスト側に課金)が設定されている場合は注意が必要です。Lake Formationでは、アクセスを仲介するRoleが常にRequesterになるためです。(Requester paysのバケットはLocationに登録しないことが推奨されています)
初回登録時は、自動で下記のservice-lined role「AWSServiceRoleForLakeFormationDataAccess」が作成されます。
Data Locationのアクセス権限追加
Data Lake Locationに設定したS3パス(Data Location)配下のデータをData CatalogのTableに追加するために、Data LocationとRoleを紐づけます。
Databaseの追加
Data Catalog>Databasesの[Create database]ボタンから、データベ ースを作成します。
Lake FormationでDatabaseを作成した場合、裏でGlue Databaseが作成されます。そのため、Glueのコンソールから同じ名称のデータベースが確認できます。
DatabaseにLF-Tagsを追加
以下のLF-TagをDatabaseに追加し、対象のTagを持つuser/roleから利用できるようにします。DatabaseにLF-Tagを設定した場合、Databaseに紐づくTableにLF-Tagが継承されます。
- Key : maintenance
- Value: crawler
Glue Crawler作成・実行
crawler作成
以下のような設定でcrawlerを作成しました。Service Roleには、最初に作成したRoleを利用します。crawlerは実行スケジュールやSchema Updateの動作を設定できますが、今回はデフォルトのままとしています。
CrawlerがSchemaを判別するために利用するデータは、最初の1MBまたは1000行(2022/01時点)という点です。それ以降のデータや、追加されたデータにエラー(途中の改行でカラム数が異なっていることや、カラムにないデータが追加されているなど)が含まれる場合、Schemaの利用時にエラーが発生します。そのため、データのバリデーションの仕組みを別途、検討する必要があります。
crawlerの実行
「Run crawler」から作成したcrawlerを実行します。実行後にTables addedが1となります。
[Tables]から作成されたテーブルが表示できます。
今回作成したバケット配下のフォルダがパーティションとして検出されていることは「View partitions」から確認できます。
テーブルへLT-Tagを追加
Lake Formationのコンソールで作成したTableを表示し、LT-Tag(source:helpful_sentences)を追加します。souce:helpful_sentencesタグは、「test_user」ユーザに付与したタグです。
Athenaからクエリ実行
test_userからAthenaコンソールにログインし、下記の操作を検証します。
Athenaの「設定」タブから結果格納先のS3(Data Lakeと別)を設定します。設定後にクエリエディタで作成したテーブルへのSELECTを実行します。
参考資料
- Lake Formation公式ドキュメント
- How to Use Glue Crawlers Efficiently to Build Your Data Lake Quickly - AWS Online Tech Talks
- Glue Cralwer利用にフォーカスしてオプションなどを説明しているため、Glue Catalog/Crawlerの理解に役立つと思います。
最後に
Lake Formationは色々な設定がポチポチっとクリックにより設定できるため、Data Lakeの権限周りを含めた開始のハードルを下げてくれます。反面、実際の運用を考えた場合は、自動で設定されたリソースの設定や権限まわりは、理解しておく方が良いと感じました。Glueとの統合の部分は、もう少しわかりやすくなったら嬉しいですね。
データ分析基盤は、データ取り込みや可視化も必要なため、Lake Formationは「データ分析環境を作る」機能ではなく、現時点ではData Lakeのアクセス制御を一元管理する機能がメインだと思いました。最近はGoverned Tableなど新機能が出てきているので、将来的には少し違う位置づけになるかもしれません。
以上、nkhrでした。